﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Linq;
using System.Linq;

namespace VisualRibbonEditor
{
	public class Deleter
	{
		public static void DeleteButton(XElement button)
		{
			XElement baseRoot = button.Ancestors().Last();

			string buttonId = button.Attribute("Id").Value;

			//remove the button from the base xml
			button.Remove();

			//remove the button from the diff xml
			XElement diffButton = MainWindow.CurrentSolution.RibbonDiffXml
				.Descendants("Button").Where(x => x.Attribute("Id").Value == buttonId).FirstOrDefault();
			if (diffButton != null)
			{
				//if the parent of the diffbutton only contains just this button, then the entire CustomAction can be deleted
				if (diffButton.Parent.Elements().Count() <= 1)
				{
					XElement customAction = diffButton.Ancestors("CustomAction").FirstOrDefault();
					if( customAction != null)
					{
						customAction.Remove();
					}
				}
				else
				{
					//otherwise just remove this button from CustomAction
					diffButton.Remove();
				}
			}

			//find out if any other buttons use the same action
			string commandId = button.Attribute("Command").Value;
			int numberUsingCommand = baseRoot.Descendants("Button").Where(x => x.AttributeValue("Command") == commandId).Count();
			if (numberUsingCommand == 0)
			{
				//delete the command
				DeleteCommand(baseRoot, commandId);
				DeleteCommand(MainWindow.CurrentSolution.RibbonDiffXml, commandId);
			}

			//delete any labels used by the button
			var labelAtts = button.Attributes().Where(a => a.Value.StartsWith("$LocLabels:"));
			foreach( var att in labelAtts)
			{
				DeleteLocLabel(att.Value.Replace("$LocLabels:", "").Trim());
			}
		}



		public static void DeleteCommand(XElement rootElement, string commandId)
		{
			//find the command
			XElement commandDefinition =
				rootElement.Descendants("CommandDefinition").Where(x => x.AttributeValue("Id") == commandId).FirstOrDefault();
			
			//remove the command
			if( commandDefinition != null)
			{
				commandDefinition.Remove();
			}		
		}

		public static void DeleteLocLabel(string locLabelId)
		{
			XElement rootElement = MainWindow.CurrentSolution.RibbonDiffXml;
			XElement customActions = rootElement.Descendants("CustomActions").FirstOrDefault();
			
			//find all uses of this label
			string pointerAttributeValue = "$LocLabels:" + locLabelId;
			var allUsesOfTheLabel = customActions.Descendants().Attributes()
				.Where(a => string.Compare(a.Value, pointerAttributeValue, StringComparison.InvariantCultureIgnoreCase) == 0);

			//if there are no uses of this label, then it can be deleted
			if (allUsesOfTheLabel.Count() == 0)
			{
				XElement locLabel =
					rootElement.Descendants("LocLabel").Where(e => e.AttributeValue("Id") == locLabelId).FirstOrDefault();
				if( locLabel != null)
				{
					locLabel.Remove();
				}
			}
		}

		public static bool GroupCanBeDeleted(XElement group)
		{
			string groupId = group.AttributeValue("Id");
			XElement groupFromDiffXml = MainWindow.CurrentSolution.RibbonDiffXml
				.Descendants("Group")
				.Where(x => x.AttributeValue("Id") == groupId).FirstOrDefault();

			return (groupFromDiffXml != null);
		}

		public static void DeleteGroup(XElement group)
		{
			DeleteGroupScales(group);
			////find the group's scales and remove them
			//string groupId = group.AttributeValue("Id");
			//foreach (XElement scale in group
			//    .Ancestors("Tab")
			//    .FirstOrDefault().Element("Scaling")
			//    .Elements()
			//    .Where(x => x.AttributeValue("GroupId") == groupId).ToArray())
			//{
			//    //remove scale from diffXml
			//    string scaleId = scale.AttributeValue("Id");
			//    RemoveCustomActionControl(scaleId);
				
			//    //remove scale from baseXml
			//    scale.Remove();
			//}

			//remove group from DiffXml
			RemoveCustomActionControl(group.AttributeValue("Id"));

			//remove group from baseXml
			group.Remove();

			//delete any labels used by the group
			var labelAtts = group.Attributes().Where(a => a.Value.StartsWith("$LocLabels:"));
			foreach (var att in labelAtts)
			{
				DeleteLocLabel(att.Value.Replace("$LocLabels:", "").Trim());
			}
		}

		public static void DeleteGroupScales(XElement group)
		{
			//find the group's scales and remove them
			string groupId = group.AttributeValue("Id");
			foreach (XElement scale in group
				.Ancestors("Tab")
				.FirstOrDefault().Element("Scaling")
				.Elements()
				.Where(x => x.AttributeValue("GroupId") == groupId).ToArray())
			{
				//remove scale from diffXml
				string scaleId = scale.AttributeValue("Id");
				RemoveCustomActionControl(scaleId);

				//remove scale from baseXml
				scale.Remove();
			}
		}


		/// <summary>
		/// Finds a control by ID in the diffXml and removes it.
		/// </summary>
		private static void RemoveCustomActionControl(string controlId)
		{
			if (string.IsNullOrEmpty(controlId))
			{
				throw new ArgumentException("controlId");
			}

			//find the control in the ribbondiffxml
			XElement customActions = MainWindow.CurrentSolution.RibbonDiffXml.Element("CustomActions");
			XElement control = customActions.Descendants().Where(x => x.AttributeValue("Id") == controlId).FirstOrDefault();
			if (control != null)
			{
				//found the control in the CustomActions section of ribbondiffxml...
				if (control.Parent.Name.LocalName == "CommandUIDefinition")
				{
					//if its parented by commandUIDefinition then we can remove the entire parent CustomAction
					XElement parentCustomAction = control.Ancestors("CustomAction").FirstOrDefault();
					if (parentCustomAction != null)
					{
						parentCustomAction.Remove();
						return;
					}
				}

				//otherwise we just remove the control, leaving its parent in the customAction
				control.Remove();
			}
		}

		 


	}
}
